/*
    Copyright © 2013 by Maxim Biro <nurupo.contributions@gmail.com>
    Copyright © 2014-2019 by The qTox Project Contributors

    This file is part of qTox, a Qt-based graphical interface for Tox.

    qTox is libre software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    qTox is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with qTox.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once


#include "audio/iaudiosettings.h"
#include "../core/icoresettings.h"
#include "../core/toxencrypt.h"
#include "../core/toxfile.h"
#include "../persistence/ifriendsettings.h"
#include "../persistence/inotificationsettings.h"
#include "../video/ivideosettings.h"


#include <map>
#include <mutex>

class Profile;

class Settings :
                 public ICoreSettings
                ,public IAudioSettings
                , public IVideoSettings
{


public:
    static Settings& getInstance();
    static void destroyInstance();
    void loadGlobal();
    std::string& getSimpleId();
    void setSimpleId(std::string& id);

private:

    Settings();
    ~Settings();
    Settings(Settings& settings) = delete;
    Settings& operator=(const Settings&) = delete;

    template <typename T>
    bool setVal(T& savedVal, T newVal);

    void save2File();
private:
    bool loaded;
    std::string simpleId;
    static Settings* settings;
    static const std::string globalSettingsFile;

    // IVideoSettings interface
public:
    std::string getVideoDev() const;
    void setVideoDev(const std::string &deviceSpecifier);
    bool getScreenGrabbed() const;
    void setScreenGrabbed(bool value);
    float getCamVideoFPS() const;
    void setCamVideoFPS(float newValue);

    // ICoreSettings interface
public:
    bool getEnableIPv6() const;
    void setEnableIPv6(bool enable);
    bool getForceTCP() const;
    void setForceTCP(bool enable);
    bool getEnableLanDiscovery() const;
    void setEnableLanDiscovery(bool enable);
    std::string getProxyAddr() const;
    void setProxyAddr(const std::string &address);
    ProxyType getProxyType() const;
    void setProxyType(ProxyType type);
    uint16_t getProxyPort() const;
    void setProxyPort(uint16_t port);

    // IAudioSettings interface
public:
    std::string getInDev() const;
    void setInDev(const std::string &deviceSpecifier);
    bool getAudioInDevEnabled() const;
    void setAudioInDevEnabled(bool enabled);
    std::string getOutDev() const;
    void setOutDev(const std::string &deviceSpecifier);
    bool getAudioOutDevEnabled() const;
    void setAudioOutDevEnabled(bool enabled);
    double getAudioInGainDecibel() const;
    void setAudioInGainDecibel(double dB);
    double getAudioThreshold() const;
    void setAudioThreshold(double percent);
    int getOutVolume() const;
    int getOutVolumeMin() const;
    int getOutVolumeMax() const;
    void setOutVolume(int volume);
    int getAudioBitrate() const;
    void setAudioBitrate(int bitrate);
    bool getEnableTestSound() const;
    void setEnableTestSound(bool newValue);
};
